package top.fwpsl.jvm;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author: 风戏fw
 * @date: 2022/8/18
 * @description: Class类功能梳理
 */
public class ClassUtil {

    /**
     * 解析类的结构
     *
     * @param clazz
     * @return
     */
    public static String getClassAllStr(Class<?> clazz) {
        StringBuilder s = new StringBuilder();

        // 包信息
        s.append("package " + clazz.getPackage().getName() + "; \n\n");

        // 注解列表信息
        for (Annotation annotation : clazz.getDeclaredAnnotations()) {
            s.append("@" + annotation.annotationType().getSimpleName());
        }

        String classType = " class ";
        if (clazz.isAnnotation()) {
            classType = " @interface ";
        } else if (clazz.isInterface()) {
            classType = " interface ";
        } else if (clazz.isEnum()) {
            classType = " enum ";
        }

        // Class类的getName方法
        // getModifiers() 作为整数返回 成员或构造方法的Java语言修饰符
        s.append(Modifier.toString(clazz.getModifiers()) + classType + clazz.getSimpleName());

        // 父类信息
        Class superclass = clazz.getSuperclass();
        if (superclass != null && !Object.class.getSimpleName().equals(superclass.getSimpleName())) {
            s.append(" extends " + superclass.getSimpleName());
        }

        // 实现的所有接口信息（一个类可以实现多个接口）
        Class[] interfaces = clazz.getInterfaces();
        if (interfaces.length > 0) {
            s.append(" implements ");
            int count = 0;
            for (Class i : interfaces) {
                if (count > 0) {
                    s.append(", ");
                }
                s.append(i.getSimpleName());
                count++;
            }
        }
        s.append(" {\n\n");

        //获取所有的属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            s.append("\t");
            // 获取属性的修饰符列表,返回的修饰符是一个数字，每个数字是修饰符的代号
            // 用Modifier类的toString转换成字符串
            s.append(Modifier.toString(f.getModifiers()));
            if (f.getModifiers() != 0) {
                s.append(" ");
            }
            // 获取属性的类型
            s.append(f.getType().getSimpleName());
            s.append(" ");
            // 获取属性的名字
            s.append(f.getName());
            s.append(";\n\n");
        }
        s.append("\n");

        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor c : constructors) {
            s.append("\t");
            s.append(Modifier.toString(c.getModifiers()));
            s.append(" ");
            //类名
            s.append(clazz.getSimpleName());
            s.append("(");
            Class[] parameterTypes = c.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 1) {
                    s.append(", ");
                }
                s.append(parameterTypes[i].getSimpleName());
            }
            s.append("){}\n\n");
        }
        s.append("\n");

        // 获取所有的Method（包括私有的）
        Method[] methods = clazz.getDeclaredMethods();
        for (Method m : methods) {
            s.append("\t");
            // 获取修饰符列表
            s.append(Modifier.toString(m.getModifiers()));
            s.append(" ");
            // 获取方法的返回值类型
            s.append(m.getReturnType().getSimpleName());
            s.append(" ");
            // 获取方法名
            s.append(m.getName());
            s.append("(");
            // 方法的修饰符列表（一个方法的参数可能会有多个）
            Class[] parameterTypes = m.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 1) {
                    s.append(", ");
                }
                s.append(parameterTypes[i].getSimpleName());
            }
            s.append(") {}\n\n");
        }
        s.append("}");

        return s.toString();
    }

    /**
     * 是否是接口
     *
     * @param clazz
     * @return
     */
    public static boolean isInterface(Class<?> clazz) {
        return clazz.isInterface();
    }

    /**
     * 是否是该Class或该Class子类的一个实例
     *
     * @param clazz
     * @param obj
     * @return
     */
    public static boolean isInstance(Class<?> clazz, Object obj) {
        return clazz.isInstance(obj);
    }

    /**
     * 是否是该Class或该Class子类的一个实例
     *
     * @param clazz
     * @param cls
     * @return
     */
    public static boolean isAssignableFrom(Class<?> clazz, Class<?> cls) {
        return clazz.isAssignableFrom(cls);
    }

    /**
     * 是否是基本类型
     *
     * @param clazz
     * @return
     */
    public static boolean isPrimitive(Class<?> clazz) {
        return clazz.isPrimitive();
    }

    /**
     * 是否是基本类型
     *
     * @param clazz
     * @return
     */
    public static boolean isArray(Class<?> clazz) {
        return clazz.isArray();
    }

    /**
     * 是否是一个注解
     * 注解是特殊的接口
     *
     * @param clazz
     * @return
     */
    public static boolean isAnnotation(Class<?> clazz) {
        return clazz.isAnnotation();
    }

    /**
     * 是指定类型的注解存在于此元素上
     *
     * @param clazz
     * @param annotation
     * @return
     */
    public static boolean isAnnotationPresent(Class<?> clazz, Class<? extends Annotation> annotation) {
        return clazz.isAnnotationPresent(annotation);
    }

    /**
     * 是否是枚举类
     *
     * @param clazz
     * @return
     */
    public static boolean isEnum(Class<?> clazz) {
        return clazz.isEnum();
    }

}
